package com.codi.bus.core.service.impl;

import com.codi.base.util.DateUtils;
import com.codi.base.util.StringUtil;
import com.codi.bus.constant.GlobalConstant;
import com.codi.bus.core.dao.*;
import com.codi.bus.core.domain.*;
import com.codi.bus.core.service.organ.OrganBankService;
import com.codi.bus.core.util.ThreadPoolExecutorUtil;
import com.codi.bus.core.util.ValueUtil;
import com.codi.fcloud.ufx.UfxSDKFactory;
import com.codi.fcloud.ufx.constant.HSInputParameterNames;
import com.codi.fcloud.ufx.constant.UrlConstants;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * @Author: zengxl
 * @Description:
 * @Date: 2018/4/23 13:48
 */
@Service
@Slf4j
public class LocaldataTradeOrderService  extends UfxSDKFactory {

    private final String redisKey = "preFundScheduleProtocolIdList";
    private final String redisOrderKey = "unSelectTradeOrderFromHs";
    @Autowired
    private TradeOrdersDao tradeOrdersDao;
    @Autowired
    private PortfolioTradeAccoDao portfolioTradeAccoDao;
    @Autowired
    private LocaldataScheduledService localdataScheduledService;
    @Autowired
    private RedisTemplate<String, String> stringRedisTemplate;
    private ThreadPoolExecutorUtil util = new ThreadPoolExecutorUtil(false);

    @Autowired
    private UserBankDao userBankDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private OrganBankService organBankService;

    @Autowired
    private OrganProfileDao organProfileDao;

    @Transactional
    public void init(){
        String trustWay = apiValueMap.get(HSInputParameterNames.TRUST_WAY);
        Map<String, Object> request = Maps.newHashMap();
        request.put("trust_way", trustWay); // 交易委托方式
        request.put("request_num", GlobalConstant.MAX_REQUEST_NUM.toString());

        Map<String, Object> request1 = Maps.newHashMap();
        request1.put("request_num",GlobalConstant.MAX_REQUEST_NUM); // 请求行数
        request1.put("reqry_recordsum_flag", "0"); // 重新统计总记录数标志
        request1.put("qry_beginrownum","0");//查询起始行号
        Map<String,Long> userMap = Maps.newHashMap();
        List<User> users = userDao.getAllUser();
        for (User user : users) {
            if (user == null || StringUtil.isEmpty(user.getExternalClientId())) {
                continue;
            }
            userMap.put(user.getExternalClientId(),user.getUserId());
        }
        log.info("执行申请交易数据。。。。");
        List<TradeOrders> orders = tradeOrdersDao.selectByTaconfirmFlag(TradeOrders.builder().taconfirmFlag("9").build());
        log.info("数据量：{}",orders.size());
        for(TradeOrders order : orders){
            if(StringUtils.isBlank(order.getClientId())){
                continue;
            }
            Long userId = userMap.get(order.getClientId());
            if(userId == null){
                continue;
            }
            request.put("allot_no", order.getAllotNo()); // 普通单号
            Map<String, Object> response = getUfxSDK().transact(getTarget(), request);
            String allot_no = ValueUtil.getObjStr(response.get("allot_no"));
            String fund_code = ValueUtil.getObjStr(response.get("fund_code"));//"fund_code": "200010",
            String trade_acco = ValueUtil.getObjStr(response.get("trade_acco"));//"trade_acco": "ZHLC000000000919",
            String success_type = ValueUtil.getObjStr(response.get("success_type"));//"success_type": "0",
            if(!"0".equals(success_type)){
                log.error("数据本地化：用户：{} 通过申请编号：{} 查询失败，申请单类型（0=普通单号  1=组合单号  2=原申请单号）：{}",userId,order.getAllotNo(),"0");
                continue;
            }
            if(allot_no.equals("") || fund_code.equals("") || trade_acco.equals("")){
                log.error("数据本地化：申请编号、基金代码、交易账号不能为空！");
                continue;
            }
            insert(order,response,userId.intValue());

            request1.put("allot_no", getString(order.getAllotNo()));//	C24	申请编号	N
            Map<String, Object> map = getUfxSDK().transact(UrlConstants.PREFIX_SALE + UrlConstants.TRADE_CONFIRM_QRY,request1);
            success_type = ValueUtil.getObjStr(map.get("success_type"));//"success_type": "0",
            if(!"0".equals(success_type)){
                log.error("数据本地化：通过查询交易确认接口更新订单状态，查询失败，申请编号：{}",order.getAllotNo());
                continue;
            }
            allot_no = ValueUtil.getObjStr(map.get("allot_no"));
            fund_code = ValueUtil.getObjStr(map.get("fund_code"));//"fund_code": "200010",
            trade_acco = ValueUtil.getObjStr(map.get("trade_acco"));//"trade_acco": "ZHLC000000000919",
            if(allot_no.equals("") || fund_code.equals("") || trade_acco.equals("")){
                log.error("数据本地化：通过查询交易确认接口更新订单状态，查询到的申请编号:{}、基金代码:{}、交易账号:{}不能为空！！",allot_no,fund_code,trade_acco);
                continue;
            }
            if(!allot_no.equals(order.getAllotNo()) || !fund_code.equals(order.getFundCode())
                || !trade_acco.equals(order.getTradeAcco())){
                log.error("数据本地化：通过查询交易确认接口更新订单状态，查询到的申请编号、基金代码、交易账号与原交易单不匹配");
                continue;
            }
            update(map,order);

        }

        log.info("执行完成!!");
    }



    /**
     * 每日定时任务执行，执行内容如下：
     * 1、查询当日的定投协议，判断是否存在交易记录，如果无交易记录，存储在缓存中，以便明日继续查询
     * 2、查询当日未确认的交易数据，通过申请编号查询恒生确认交易接口，更新交易数据
     */
    @Transactional
    public void updateOrder(boolean isAll){
        //获取当日的定投协议
        List<Scheduled>  scheduleProtocolIdList = localdataScheduledService.getScheduledProtocolId(new Date());
        SetOperations setOperations = stringRedisTemplate.opsForSet();
        //记录未执行的定投协议
        List<Scheduled> unExecList = Lists.newArrayList();

        //从缓存中获取昨日未查询到数据的定投协议
        long preScheduleProtocolIdSize = setOperations.size(redisKey);
        if(preScheduleProtocolIdSize > 0){
            Set<Scheduled> preSet = setOperations.members(redisKey);
            for(Scheduled temp:preSet){
                scheduleProtocolIdList.add(temp);
            }
        }
        //查询未确认的所有订单
        TradeOrders vo = new TradeOrders();
        if(!isAll){
            vo.setTaconfirmFlag("9");
        }
        List<TradeOrders> ordersList = tradeOrdersDao.selectByTaconfirmFlag(vo);
        if(ordersList == null){
            ordersList = Lists.newArrayList();
        }

        String date = DateUtils.getFormatedDate(new Date(),"yyyyMMdd");
        for(Scheduled schedule : scheduleProtocolIdList){
            String protocolId = schedule.getScheduledProtocolId();
            String tradeAcco = schedule.getBankName();
            String clientId = null;
            UserBank userBank = userBankDao.getByTradeAccount(tradeAcco);
            if (userBank != null && userBank.getUserId() != null) {
                User user = userDao.getEntity(userBank.getUserId());
                clientId = user.getExternalClientId();
            } else {
                OrganBank organBank = organBankService.selectByTradeAccount(tradeAcco);
                if (organBank != null && organBank.getProfileId() != null) {
                    OrganProfile organProfile = organProfileDao.qryByProfileId(organBank.getProfileId());
                    clientId = organProfile.getExternalClientId();
                }
            }
            long userId = schedule.getUserId();
            String trustWay = apiValueMap.get(HSInputParameterNames.TRUST_WAY);
            Map<String, Object> request = new HashMap<String, Object>();
            request.put("trust_way", trustWay); // 交易委托方式
            request.put("scheduled_protocol_id",protocolId);
            request.put("trade_acco",tradeAcco);
            request.put("begin_date",date);
            request.put("end_date",date);
            request.put("request_num", GlobalConstant.MAX_REQUEST_NUM.toString()); // 请求行数
            List<Map<String, Object>> response = getUfxSDK().query(getTarget(), request);
            for(Map<String, Object> map:response){
                String allot_no = ValueUtil.getObjStr(map.get("allot_no"));
                String fund_code = ValueUtil.getObjStr(map.get("fund_code"));//"fund_code": "200010",
                String trade_acco = ValueUtil.getObjStr(map.get("trade_acco"));//"trade_acco": "ZHLC000000000919",
                String success_type = ValueUtil.getObjStr(map.get("success_type"));//"success_type": "0",
                if(!"0".equals(success_type)){
                    log.error("数据本地化：用户：{} 通过申请编号：{} 查询失败，组合标识：{}",userId,allot_no,false);
                    continue;
                }
                if(allot_no.equals("") || fund_code.equals("") || trade_acco.equals("")){
                    unExecList.add(schedule);
                    continue;
                }
                TradeOrders data = tradeOrderExec(schedule.getUserId(), tradeAcco, "定投", map, 0, true, clientId);
                ordersList.add(data);
            }
        }
        //保存为查询到数据的定投协议
        stringRedisTemplate.delete(redisKey);
        if(unExecList.size()> 0){
            for(Scheduled temp : unExecList){
                setOperations.add(redisKey,temp);
            }
        }
        //从缓存中获取新增交易记录失败的订单号
        Set<String> orderSet = setOperations.members(redisOrderKey);
        Set<String> newOrderSet = Sets.newHashSet();
        for(String key:orderSet){
            String[] keys = key.split("codi");
            //String value = userId+"codi"+allotNo+"codi"+allotNoType+"codi"+tradeSource+"codi"+tradeAcco;
            int userId = Integer.parseInt(keys[0]);
            String allotNo = keys[1];
            int allotNoType = Integer.parseInt(keys[2]);
            String tradeSource = keys[3];
            String tradeAcco = keys[4];

            String trustWay = apiValueMap.get(HSInputParameterNames.TRUST_WAY);
            Map<String, Object> request = new HashMap<String, Object>();
            request.put("trust_way", trustWay); // 交易委托方式
            if(allotNoType == 0){
                request.put("allot_no", allotNo); // 普通单号
            }else if(allotNoType == 1){
                request.put("portfolio_allot_no", allotNo); // 组合申请编号
            }else if(allotNoType == 2){
                request.put("original_appno", allotNo); // 原申请单号
            }else{
                continue;
            }
            request.put("request_num", GlobalConstant.MAX_REQUEST_NUM.toString()); // 请求行数
            List<Map<String, Object>> response = getUfxSDK().query(getTarget(), request);
            for(Map<String, Object> map:response){
                String allot_no = ValueUtil.getObjStr(map.get("allot_no"));
                String fund_code = ValueUtil.getObjStr(map.get("fund_code"));//"fund_code": "200010",
                String trade_acco = ValueUtil.getObjStr(map.get("trade_acco"));//"trade_acco": "ZHLC000000000919",
                String success_type = ValueUtil.getObjStr(map.get("success_type"));//"success_type": "0",
                if(!"0".equals(success_type)){
                    log.error("数据本地化：用户：{} 通过申请编号：{} 查询失败，申请单类型（0=普通单号  1=组合单号  2=原申请单号）：{}",userId,allotNo,allotNoType);
                    continue;
                }
                if(allot_no.equals("") || fund_code.equals("") || trade_acco.equals("")){
                    log.error("数据本地化：申请编号、基金代码、交易账号不能为空！！");
                    newOrderSet.add(key);
                    continue;
                }
                TradeOrders data = tradeOrderExec(userId, tradeAcco, tradeSource, map, allotNoType, true, null);
                ordersList.add(data);
            }
        }
        stringRedisTemplate.delete(redisOrderKey);
        if(newOrderSet.size()> 0){
            for(String temp : newOrderSet){
                setOperations.add(redisOrderKey,temp);
            }
        }

        if(ordersList == null || ordersList.size() == 0){
            log.info("数据本地化更新：本次未查询到未确认订单~");
            return;
        }
        Map<String, Object> request = new HashMap<>();
        request.put("request_num",GlobalConstant.MAX_REQUEST_NUM); // 请求行数
        request.put("reqry_recordsum_flag", "0"); // 重新统计总记录数标志
        request.put("qry_beginrownum","0");//查询起始行号
        for(TradeOrders orders:ordersList){
            request.put("allot_no", getString(orders.getAllotNo()));//	C24	申请编号	N
            Map<String, Object> map = getUfxSDK().transact(UrlConstants.PREFIX_SALE + UrlConstants.TRADE_CONFIRM_QRY,request);
            String success_type = ValueUtil.getObjStr(map.get("success_type"));//"success_type": "0",
            if(!"0".equals(success_type)){
                log.error("数据本地化：通过查询交易确认接口更新订单状态，查询失败，申请编号：{}",orders.getAllotNo());
                continue;
            }
            String allot_no = ValueUtil.getObjStr(map.get("allot_no"));
            String fund_code = ValueUtil.getObjStr(map.get("fund_code"));//"fund_code": "200010",
            String trade_acco = ValueUtil.getObjStr(map.get("trade_acco"));//"trade_acco": "ZHLC000000000919",
            if(allot_no.equals("") || fund_code.equals("") || trade_acco.equals("")){
                log.error("数据本地化：通过查询交易确认接口更新订单状态，查询到的申请编号:{}、基金代码:{}、交易账号:{}不能为空！！",allot_no,fund_code,trade_acco);
                continue;
            }
            if(!allot_no.equals(orders.getAllotNo()) || !fund_code.equals(orders.getFundCode())
                || !trade_acco.equals(orders.getTradeAcco())){
                log.error("数据本地化：通过查询交易确认接口更新订单状态，查询到的申请编号、基金代码、交易账号与原交易单不匹配");
                continue;
            }
            update(map,orders);
        }

    }

    private void update(Map<String, Object> map,TradeOrders orders){

        String ofund_type = ValueUtil.getObjStr(map.get("ofund_type"));
        orders.setFundType(ofund_type);
        String taconfirm_flag = ValueUtil.getObjStr(map.get("taconfirm_flag"));
        orders.setTaconfirmFlag(taconfirm_flag);
        String ta_serial_id = ValueUtil.getObjStr(map.get("ta_serial_id"));
        orders.setTaSerialId(ta_serial_id);
        String affirm_date = ValueUtil.getObjStr(map.get("affirm_date"));
        orders.setAffirmDate(affirm_date);
        String trade_confirm_type = ValueUtil.getObjStr(map.get("trade_confirm_type"));
        if(trade_confirm_type.equals("")){
            trade_confirm_type = "0";
        }
        orders.setTradeConfirmType(new BigDecimal(trade_confirm_type));
        String trade_confirm_balance = ValueUtil.getObjStr(map.get("trade_confirm_balance"));
        if(trade_confirm_balance.equals("")){
            trade_confirm_balance = "0";
        }
        orders.setTradeConfirmBalance(new BigDecimal(trade_confirm_balance));
        String net_value = ValueUtil.getObjStr(map.get("net_value"));
        if(net_value.equals("")){
            net_value = "0";
        }
        orders.setNetValue(new BigDecimal(net_value));
        String auto_buy = ValueUtil.getObjStr(map.get("auto_buy"));//"auto_buy": "",
        orders.setAutoBuy(auto_buy);
        String unpaid_income = ValueUtil.getObjStr(map.get("unpaid_income"));
        if(unpaid_income.equals("")){
            unpaid_income = "0";
        }
        orders.setUnpaidIncome(new BigDecimal(unpaid_income));
        String cash_nopay_share = ValueUtil.getObjStr(map.get("cash_nopay_share"));
        if(cash_nopay_share.equals("")){
            cash_nopay_share = "0";
        }
        orders.setCashNopayShare(new BigDecimal(cash_nopay_share));
        String cash_share = ValueUtil.getObjStr(map.get("cash_share"));
        if(cash_share.equals("")){
            cash_share = "0";
        }
        orders.setCashShare(new BigDecimal(cash_share));
        String fail_cause = ValueUtil.getObjStr(map.get("fail_cause"));
        orders.setFailCause(fail_cause);
        String fare_sx = ValueUtil.getObjStr(map.get("fare_sx"));
        if(fare_sx.equals("")){
            fare_sx = "0";
        }
        orders.setFareSx(new BigDecimal(fare_sx));
        String ta_fare = ValueUtil.getObjStr(map.get("ta_fare"));
        if(ta_fare.equals("")){
            ta_fare = "0";
        }
        orders.setTaFare(new BigDecimal(ta_fare));
        String after_fare = ValueUtil.getObjStr(map.get("after_fare"));
        if(after_fare.equals("")){
            after_fare = "0";
        }
        orders.setAfterFare(new BigDecimal(after_fare));
        orders.setLastupdateTime(DateUtils.getCurrTime());
        tradeOrdersDao.updateByAllotNoSelective(orders);
        log.info("交易确认查询更新成功...");
    }

    /**
     * 新增交易申请接口查询到的交易数据
     * @param userId
     * @param allotNo
     * @param allotNoType 0=普通单号  1=组合单号  2=原申请单号
     * @param tradeSource
     * @param tradeAcco
     */
    public void addApplyOrder(Integer userId, String allotNo, int allotNoType, String tradeSource, String tradeAcco, String clientId) {
        util.getThreadPoolExecutor().execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                String trustWay = apiValueMap.get(HSInputParameterNames.TRUST_WAY);
                Map<String, Object> request = new HashMap<String, Object>();
                request.put("trust_way", trustWay); // 交易委托方式
                if(allotNoType == 0){
                    request.put("allot_no", allotNo); // 普通单号
                }else if(allotNoType == 1){
                    request.put("portfolio_allot_no", allotNo); // 组合申请编号
                }else if(allotNoType == 2){
                    request.put("original_appno", allotNo); // 原申请单号
                }else{
                    log.error("数据本地化：用户：{} 通过申请编号：{} 查询失败，申请单类型（0=普通单号  1=组合单号  2=原申请单号）：{}",userId,allotNo,allotNoType);
                    return;
                }
                request.put("request_num", GlobalConstant.MAX_REQUEST_NUM.toString()); // 请求行数
                List<Map<String, Object>> response = getUfxSDK().query(getTarget(), request);
                SetOperations setOperations = stringRedisTemplate.opsForSet();
                for(Map<String, Object> map:response){
                    String allot_no = ValueUtil.getObjStr(map.get("allot_no"));
                    String fund_code = ValueUtil.getObjStr(map.get("fund_code"));//"fund_code": "200010",
                    String trade_acco = ValueUtil.getObjStr(map.get("trade_acco"));//"trade_acco": "ZHLC000000000919",
                    String success_type = ValueUtil.getObjStr(map.get("success_type"));//"success_type": "0",
                    if(!"0".equals(success_type)){
                        log.error("数据本地化：用户：{} 通过申请编号：{} 查询失败，申请单类型（0=普通单号  1=组合单号  2=原申请单号）：{}",userId,allotNo,allotNoType);
                        String value = userId+"codi"+allotNo+"codi"+allotNoType+"codi"+tradeSource+"codi"+tradeAcco;
                        setOperations.add(redisOrderKey,value);
                        continue;
                    }
                    if(allot_no.equals("") || fund_code.equals("") || trade_acco.equals("")){
                        log.error("数据本地化：申请编号、基金代码、交易账号不能为空！！下次继续查询");
                        String value = userId+"codi"+allotNo+"codi"+allotNoType+"codi"+tradeSource+"codi"+tradeAcco;
                        setOperations.add(redisOrderKey,value);
                        continue;
                    }
                    tradeOrderExec(userId, tradeAcco, tradeSource, map, allotNoType, false, clientId);
                }
            }
        });

    }

    private void insert(TradeOrders orders,Map<String, Object> map,int userId){
        String allot_no = ValueUtil.getObjStr(map.get("allot_no"));
        String fund_code = ValueUtil.getObjStr(map.get("fund_code"));//"fund_code": "200010",
        String trade_acco = ValueUtil.getObjStr(map.get("trade_acco"));//"trade_acco": "ZHLC000000000919",
        String success_type = ValueUtil.getObjStr(map.get("success_type"));//"success_type": "0",
        orders.setUserId(userId);
        orders.setAllotNo(allot_no);
        orders.setFundCode(fund_code);
        orders.setTradeAcco(trade_acco);
        orders.setSuccessType(success_type);
        orders.setTradeSource(ValueUtil.getObjStr(map.get("trade_source"))==null?"":ValueUtil.getObjStr(map.get("trade_source")));
        String fund_busin_code = ValueUtil.getObjStr(map.get("fund_busin_code"));//"fund_busin_code": "022",
        orders.setFundBusinCode(fund_busin_code);

        String ta_acco = ValueUtil.getObjStr(map.get("ta_acco"));//"ta_acco": "*20000000918",
        orders.setTaAcco(ta_acco);
        String apply_date = ValueUtil.getObjStr(map.get("apply_date"));//"20180424",
        orders.setApplyDate(apply_date);
        String order_date = ValueUtil.getObjStr(map.get("order_date"));//"order_date": "154144",需要转换
        orders.setOrderDate(order_date);
        String share_type = ValueUtil.getObjStr(map.get("share_type"));//"share_type": "A",
        orders.setShareType(share_type);
        String balance = ValueUtil.getObjStr(map.get("balance"));//"balance": "70000.00",
        if(balance.equals("")){
            balance = "0";
        }
        orders.setBalance(new BigDecimal(balance));
        String shares = ValueUtil.getObjStr(map.get("shares"));//"shares": "0.00",
        if(shares.equals("")){
            shares = "0";
        }
        orders.setShares(new BigDecimal(shares));
        String money_type = ValueUtil.getObjStr(map.get("money_type"));//"money_type": "0",
        orders.setMoneyType(money_type);
        String capital_mode = ValueUtil.getObjStr(map.get("capital_mode"));//"capital_mode": "I",
        orders.setCapitalMode(capital_mode);
        String portfolio_code = ValueUtil.getObjStr(map.get("ext_combcode"));//"portfolio_code": "0410",
        orders.setPortfolioCode(portfolio_code);

        String portfolio_allot_no = ValueUtil.getObjStr(map.get("portfolio_allot_no"));//"portfolio_allot_no": "20180423000707",
        orders.setPortfolioAllotNo(portfolio_allot_no);
        String deduct_status = ValueUtil.getObjStr(map.get("deduct_status"));//"deduct_status": "2",
        orders.setDeductStatus(deduct_status);
        String after_discount_rate = ValueUtil.getObjStr(map.get("after_discount_rate"));//"after_discount_rate": "1.0000",
        if(after_discount_rate.equals("")){
            after_discount_rate = "0";
        }
        orders.setAfterDiscountRate(new BigDecimal(after_discount_rate));
        String reserve_discount_rate = ValueUtil.getObjStr(map.get("reserve_discount_rate"));//"reserve_discount_rate": "1.0000",
        if(reserve_discount_rate.equals("")){
            reserve_discount_rate = "0";
        }
        orders.setReserveDiscountRate(new BigDecimal(reserve_discount_rate));
        String taconfirm_flag = ValueUtil.getObjStr(map.get("taconfirm_flag"));//"taconfirm_flag": "9",
        orders.setTaconfirmFlag(taconfirm_flag);
        String original_date = ValueUtil.getObjStr(map.get("original_date"));//"original_date": "20180423",
        orders.setOriginalDate(original_date);
        String hope_date = ValueUtil.getObjStr(map.get("hope_date"));//"hope_date": "",
        orders.setHopeDate(hope_date);
        String auto_buy = ValueUtil.getObjStr(map.get("auto_buy"));//"auto_buy": "",
        orders.setAutoBuy(auto_buy);
        String original_appno = ValueUtil.getObjStr(map.get("original_appno"));//"original_appno": "",
        orders.setOriginalAppno(original_appno);
        String target_fund_code = ValueUtil.getObjStr(map.get("target_fund_code"));//"target_fund_code": "",
        orders.setTargetFundCode(target_fund_code);
        String target_fund_type = ValueUtil.getObjStr(map.get("target_fund_type"));//"target_fund_type": "",
        orders.setTargetFundType(target_fund_type);
        String target_share_type = ValueUtil.getObjStr(map.get("target_share_type"));//"target_share_type": "",
        orders.setTargetShareType(target_share_type);
        String receivable_account = ValueUtil.getObjStr(map.get("receivable_account"));//"receivable_account": "6212261202025944442",
        orders.setReceivableAccount(receivable_account);
        String combined_error_info = ValueUtil.getObjStr(map.get("combined_error_info"));//"combined_error_info": "",
        orders.setCombinedErrorInfo(combined_error_info);
        String busin_ass_code = ValueUtil.getObjStr(map.get("busin_ass_code"));//"busin_ass_code": "28",
        orders.setBusinAssCode(busin_ass_code);
        String scheduled_protocol_id = ValueUtil.getObjStr(map.get("scheduled_protocol_id"));//"scheduled_protocol_id": "",
        orders.setScheduledProtocolId(scheduled_protocol_id);
        String protocol_period_unit = ValueUtil.getObjStr(map.get("protocol_period_unit"));//"protocol_period_unit": "",
        orders.setProtocolPeriodUnit(protocol_period_unit);
        String trade_period = ValueUtil.getObjStr(map.get("trade_period"));//"trade_period": "",
        orders.setTradePeriod(trade_period);
        orders.setCreateTime(DateUtils.getCurrTime());
        tradeOrdersDao.updateByAllotNoSelective(orders);
        log.info("数据本地化更新：已经存在申请编号：{} 的数据，本次更新交易申请信息",allot_no);

    }


    private TradeOrders tradeOrderExec(int userId, String tradeAcco, String tradeSource, Map<String, Object> map, int allotNoType, boolean select, String clientId) {

        String allot_no = ValueUtil.getObjStr(map.get("allot_no"));
        String fund_code = ValueUtil.getObjStr(map.get("fund_code"));//"fund_code": "200010",
        String trade_acco = ValueUtil.getObjStr(map.get("trade_acco"));//"trade_acco": "ZHLC000000000919",
        String success_type = ValueUtil.getObjStr(map.get("success_type"));//"success_type": "0",

        TradeOrders orders = new TradeOrders();
        orders.setClientId(clientId);
        orders.setUserId(userId);
        orders.setAllotNo(allot_no);
        orders.setFundCode(fund_code);
        orders.setTradeAcco(trade_acco);
        orders.setSuccessType(success_type);
        orders.setTradeSource(tradeSource);
        String fund_busin_code = ValueUtil.getObjStr(map.get("fund_busin_code"));//"fund_busin_code": "022",
        orders.setFundBusinCode(fund_busin_code);

        String ta_acco = ValueUtil.getObjStr(map.get("ta_acco"));//"ta_acco": "*20000000918",
        orders.setTaAcco(ta_acco);
        String apply_date = ValueUtil.getObjStr(map.get("apply_date"));//"20180424",
        orders.setApplyDate(apply_date);
        String order_date = ValueUtil.getObjStr(map.get("order_date"));//"order_date": "154144",需要转换
        orders.setOrderDate(order_date);
        String share_type = ValueUtil.getObjStr(map.get("share_type"));//"share_type": "A",
        orders.setShareType(share_type);
        String balance = ValueUtil.getObjStr(map.get("balance"));//"balance": "70000.00",
        if(balance.equals("")){
            balance = "0";
        }
        orders.setBalance(new BigDecimal(balance));
        String shares = ValueUtil.getObjStr(map.get("shares"));//"shares": "0.00",
        if(shares.equals("")){
            shares = "0";
        }
        orders.setShares(new BigDecimal(shares));
        String money_type = ValueUtil.getObjStr(map.get("money_type"));//"money_type": "0",
        orders.setMoneyType(money_type);
        String capital_mode = ValueUtil.getObjStr(map.get("capital_mode"));//"capital_mode": "I",
        orders.setCapitalMode(capital_mode);
        String portfolio_code = ValueUtil.getObjStr(map.get("ext_combcode"));//"portfolio_code": "0410",
        orders.setPortfolioCode(portfolio_code);

        String portfolio_allot_no = ValueUtil.getObjStr(map.get("portfolio_allot_no"));//"portfolio_allot_no": "20180423000707",
        orders.setPortfolioAllotNo(portfolio_allot_no);
        String deduct_status = ValueUtil.getObjStr(map.get("deduct_status"));//"deduct_status": "2",
        orders.setDeductStatus(deduct_status);
        String after_discount_rate = ValueUtil.getObjStr(map.get("after_discount_rate"));//"after_discount_rate": "1.0000",
        if(after_discount_rate.equals("")){
            after_discount_rate = "0";
        }
        orders.setAfterDiscountRate(new BigDecimal(after_discount_rate));
        String reserve_discount_rate = ValueUtil.getObjStr(map.get("reserve_discount_rate"));//"reserve_discount_rate": "1.0000",
        if(reserve_discount_rate.equals("")){
            reserve_discount_rate = "0";
        }
        orders.setReserveDiscountRate(new BigDecimal(reserve_discount_rate));
        String taconfirm_flag = ValueUtil.getObjStr(map.get("taconfirm_flag"));//"taconfirm_flag": "9",
        orders.setTaconfirmFlag(taconfirm_flag);
        String original_date = ValueUtil.getObjStr(map.get("original_date"));//"original_date": "20180423",
        orders.setOriginalDate(original_date);
        String hope_date = ValueUtil.getObjStr(map.get("hope_date"));//"hope_date": "",
        orders.setHopeDate(hope_date);
        String auto_buy = ValueUtil.getObjStr(map.get("auto_buy"));//"auto_buy": "",
        orders.setAutoBuy(auto_buy);
        String original_appno = ValueUtil.getObjStr(map.get("original_appno"));//"original_appno": "",
        orders.setOriginalAppno(original_appno);
        String target_fund_code = ValueUtil.getObjStr(map.get("target_fund_code"));//"target_fund_code": "",
        orders.setTargetFundCode(target_fund_code);
        String target_fund_type = ValueUtil.getObjStr(map.get("target_fund_type"));//"target_fund_type": "",
        orders.setTargetFundType(target_fund_type);
        String target_share_type = ValueUtil.getObjStr(map.get("target_share_type"));//"target_share_type": "",
        orders.setTargetShareType(target_share_type);
        String receivable_account = ValueUtil.getObjStr(map.get("receivable_account"));//"receivable_account": "6212261202025944442",
        orders.setReceivableAccount(receivable_account);
        String combined_error_info = ValueUtil.getObjStr(map.get("combined_error_info"));//"combined_error_info": "",
        orders.setCombinedErrorInfo(combined_error_info);
        String busin_ass_code = ValueUtil.getObjStr(map.get("busin_ass_code"));//"busin_ass_code": "28",
        orders.setBusinAssCode(busin_ass_code);
        String scheduled_protocol_id = ValueUtil.getObjStr(map.get("scheduled_protocol_id"));//"scheduled_protocol_id": "",
        orders.setScheduledProtocolId(scheduled_protocol_id);
        String protocol_period_unit = ValueUtil.getObjStr(map.get("protocol_period_unit"));//"protocol_period_unit": "",
        orders.setProtocolPeriodUnit(protocol_period_unit);
        String trade_period = ValueUtil.getObjStr(map.get("trade_period"));//"trade_period": "",
        orders.setTradePeriod(trade_period);
        TradeOrders exitOrders = tradeOrdersDao.selectByAllotNo(orders);
        if(exitOrders != null && exitOrders.getTradeId()>0){
            tradeOrdersDao.updateByAllotNoSelective(orders);
            log.info("数据本地化更新：已经存在申请编号：{} 的数据，本次更新交易申请信息",allot_no);
        }else {
            orders.setCreateTime(DateUtils.getCurrTime());
            tradeOrdersDao.insert(orders);
            log.info("数据本地化新增：新增编号：{}",allot_no);
        }

        //如果是组合申请单号，记录组合交易账号与银行卡交易账号的关系
        if(allotNoType==1){
            PortfolioTradeAcco portfolioTradeAcco = new PortfolioTradeAcco();
            portfolioTradeAcco.setUserId(userId);
            portfolioTradeAcco.setPortfolioCode(portfolio_code);
            List<PortfolioTradeAcco> portfolioTradeAccoList = portfolioTradeAccoDao.selectByPortfolioCode(portfolioTradeAcco);
            if(portfolioTradeAccoList == null || portfolioTradeAccoList.size() ==0){
                portfolioTradeAcco.setPortfolioAllotNo(allot_no);
                portfolioTradeAcco.setTradeAcco(tradeAcco);
                portfolioTradeAcco.setPortfolioTradeAcco(trade_acco);
                portfolioTradeAccoDao.insert(portfolioTradeAcco);
            }
        }
        if(select){
            return tradeOrdersDao.selectByAllotNo(orders);
        }else {
            return orders;
        }

    }

    public List<Map<String, Object>> getTradeOrder(String allotNo,int allotNoType){
        String trustWay = apiValueMap.get(HSInputParameterNames.TRUST_WAY);
        Map<String, Object> request = new HashMap<String, Object>();
        request.put("trust_way", trustWay); // 交易委托方式
        if(allotNoType == 0){
            request.put("allot_no", allotNo); // 普通单号
        }else if(allotNoType == 1){
            request.put("portfolio_allot_no", allotNo); // 组合申请编号
        }else if(allotNoType == 2){
            request.put("original_appno", allotNo); // 原申请单号
        }
        request.put("request_num", GlobalConstant.MAX_REQUEST_NUM.toString()); // 请求行数
        List<Map<String, Object>> response = getUfxSDK().query(getTarget(), request);
        return response;
    }

    @Override
    protected String getTarget() {
        return UrlConstants.PREFIX_SALE + UrlConstants.TRADE_APPLY_QRY;
    }

}
